home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pico / region.c < prev    next >
C/C++ Source or Header  |  1996-07-09  |  9KB  |  384 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: region.c,v 4.19 1996/07/09 23:55:54 mikes Exp $";
  3. #endif
  4. /*
  5.  * Program:    Region management routines
  6.  *
  7.  *
  8.  * Michael Seibel
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  *
  19.  * Pine and Pico are registered trademarks of the University of Washington.
  20.  * No commercial use of these trademarks may be made without prior written
  21.  * permission of the University of Washington.
  22.  * 
  23.  * Pine, Pico, and Pilot software and its included text are Copyright
  24.  * 1989-1996 by the University of Washington.
  25.  * 
  26.  * The full text of our legal notices is contained in the file called
  27.  * CPYRIGHT, included with this distribution.
  28.  *
  29.  */
  30. /*
  31.  * The routines in this file
  32.  * deal with the region, that magic space
  33.  * between "." and mark. Some functions are
  34.  * commands. Some functions are just for
  35.  * internal use.
  36.  */
  37. #include        <stdio.h>
  38. #include    "osdep.h"
  39. #include    "pico.h"
  40. #include    "estruct.h"
  41. #include        "edef.h"
  42.  
  43. /*
  44.  * Kill the region. Ask "getregion"
  45.  * to figure out the bounds of the region.
  46.  * Move "." to the start, and kill the characters.
  47.  * Bound to "C-W".
  48.  */
  49. killregion(f, n)
  50. {
  51.     REGION          region;
  52.     static long     times = 1L;
  53.     static long     backoff = 4L;
  54.  
  55.     if (curbp->b_mode&MDVIEW)        /* don't allow this command if    */
  56.       return(rdonly());            /* we are in read only mode    */
  57.  
  58.     if (getregion(®ion) != TRUE){
  59.     if((lastflag&CFKILL) == 0){
  60.         emlwrite("Line Deleted.%s", !(times % backoff) ? 
  61.              " (Could also use ctrl-^ to mark text for cutting)" : "");
  62.  
  63.         if(!(times++ % backoff))     /* if message shown, reset backoff */
  64.           backoff = backoff << 1;
  65.     }
  66.     
  67.     return (killtext(f, n));
  68.     }else {
  69.     mlerase();
  70.     }
  71.  
  72.     if ((lastflag&CFKILL) == 0)        /* This is a kill type  */
  73.       kdelete();            /* command, so do magic */
  74.  
  75.     thisflag |= CFKILL;            /* kill buffer stuff.   */
  76.     curwp->w_dotp = region.r_linep;
  77.     curwp->w_doto = region.r_offset;
  78.     curwp->w_markp = NULL;
  79. #ifdef    _WINDOWS
  80.     mswin_allowcopycut(NULL);
  81. #endif
  82.  
  83.     if(ldelete(region.r_size, TRUE)){
  84.     if(curwp->w_dotp == curwp->w_linep && curwp->w_dotp == curbp->b_linep){
  85.         curwp->w_force = 0;        /* Center dot. */
  86.         curwp->w_flag |= WFFORCE;
  87.     }
  88.  
  89.     return(TRUE);
  90.     }
  91.  
  92.     return (FALSE);
  93. }
  94.  
  95.  
  96. /*
  97.  * Blast the region without saving . Ask "getregion"
  98.  * to figure out the bounds of the region.
  99.  * Move "." to the start, and kill the characters.
  100.  * Bound to "C-W".
  101.  */
  102. deleteregion(f, n)
  103. {
  104.     REGION          region;
  105.  
  106.     if (curbp->b_mode&MDVIEW)        /* don't allow this command if    */
  107.       return(rdonly());            /* we are in read only mode    */
  108.  
  109.     if (getregion(®ion) == TRUE){
  110.     curwp->w_dotp = region.r_linep;
  111.     curwp->w_doto = region.r_offset;
  112.     curwp->w_markp = NULL;
  113. #ifdef    _WINDOWS
  114.     mswin_allowcopycut(NULL);
  115. #endif
  116.     if(ldelete(region.r_size, FALSE)){
  117.         if(curwp->w_dotp == curwp->w_linep
  118.            && curwp->w_dotp == curbp->b_linep){
  119.         curwp->w_force = 0;        /* Center dot. */
  120.         curwp->w_flag |= WFFORCE;
  121.         }
  122.  
  123.         return(TRUE);
  124.     }
  125.     }
  126.  
  127.     return (FALSE);
  128. }
  129.  
  130.  
  131. /*
  132.  * Copy all of the characters in the
  133.  * region to the kill buffer. Don't move dot
  134.  * at all. This is a bit like a kill region followed
  135.  * by a yank. Bound to "M-W".
  136.  */
  137. copyregion(f, n)
  138. {
  139.     register LINE   *linep;
  140.     register int    loffs;
  141.     register int    s;
  142.     REGION          region;
  143.  
  144.     if ((s=getregion(®ion)) != TRUE)
  145.       return (s);
  146.  
  147.     if ((lastflag&CFKILL) == 0)        /* Kill type command.   */
  148.       kdelete();
  149.  
  150.     thisflag |= CFKILL;
  151.     linep = region.r_linep;        /* Current line.        */
  152.     loffs = region.r_offset;        /* Current offset.      */
  153.     while (region.r_size--) {
  154.     if (loffs == llength(linep)) {  /* End of line.         */
  155.         if ((s=kinsert('\n')) != TRUE)
  156.           return (s);
  157.         linep = lforw(linep);
  158.         loffs = 0;
  159.     } else {                        /* Middle of line.      */
  160.         if ((s=kinsert(lgetc(linep, loffs).c)) != TRUE)
  161.           return (s);
  162.         ++loffs;
  163.     }
  164.     }
  165.  
  166.     return (TRUE);
  167. }
  168.  
  169.  
  170. /*
  171.  * Lower case region. Zap all of the upper
  172.  * case characters in the region to lower case. Use
  173.  * the region code to set the limits. Scan the buffer,
  174.  * doing the changes. Call "lchange" to ensure that
  175.  * redisplay is done in all buffers. Bound to
  176.  * "C-X C-L".
  177.  */
  178. lowerregion(f, n)
  179. {
  180.     register LINE   *linep;
  181.     register int    loffs;
  182.     register int    c;
  183.     register int    s;
  184.     REGION          region;
  185.     CELL            ac;
  186.  
  187.     ac.a = 0;
  188.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  189.       return(rdonly());    /* we are in read only mode    */
  190.  
  191.     if ((s=getregion(®ion)) != TRUE)
  192.       return (s);
  193.  
  194.     lchange(WFHARD);
  195.     linep = region.r_linep;
  196.     loffs = region.r_offset;
  197.     while (region.r_size--) {
  198.     if (loffs == llength(linep)) {
  199.         linep = lforw(linep);
  200.         loffs = 0;
  201.     } else {
  202.         c = lgetc(linep, loffs).c;
  203.         if (c>='A' && c<='Z'){
  204.         ac.c = c+'a'-'A';
  205.         lputc(linep, loffs, ac);
  206.         }
  207.         ++loffs;
  208.     }
  209.     }
  210.  
  211.     return (TRUE);
  212. }
  213.  
  214. /*
  215.  * Upper case region. Zap all of the lower
  216.  * case characters in the region to upper case. Use
  217.  * the region code to set the limits. Scan the buffer,
  218.  * doing the changes. Call "lchange" to ensure that
  219.  * redisplay is done in all buffers. Bound to
  220.  * "C-X C-L".
  221.  */
  222. upperregion(f, n)
  223. {
  224.     register LINE   *linep;
  225.     register int    loffs;
  226.     register int    c;
  227.     register int    s;
  228.     REGION          region;
  229.     CELL            ac;
  230.  
  231.     ac.a = 0;
  232.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  233.       return(rdonly());    /* we are in read only mode    */
  234.  
  235.     if ((s=getregion(®ion)) != TRUE)
  236.       return (s);
  237.  
  238.     lchange(WFHARD);
  239.     linep = region.r_linep;
  240.     loffs = region.r_offset;
  241.     while (region.r_size--) {
  242.     if (loffs == llength(linep)) {
  243.         linep = lforw(linep);
  244.         loffs = 0;
  245.     } else {
  246.         c = lgetc(linep, loffs).c;
  247.         if (c>='a' && c<='z'){
  248.         ac.c = c - 'a' + 'A';
  249.         lputc(linep, loffs, ac);
  250.         }
  251.         ++loffs;
  252.     }
  253.     }
  254.  
  255.     return (TRUE);
  256. }
  257.  
  258. /*
  259.  * This routine figures out the
  260.  * bounds of the region in the current window, and
  261.  * fills in the fields of the "REGION" structure pointed
  262.  * to by "rp". Because the dot and mark are usually very
  263.  * close together, we scan outward from dot looking for
  264.  * mark. This should save time. Return a standard code.
  265.  * Callers of this routine should be prepared to get
  266.  * an "ABORT" status; we might make this have the
  267.  * conform thing later.
  268.  */
  269. getregion(rp)
  270. register REGION *rp;
  271. {
  272.     register LINE   *flp;
  273.     register LINE   *blp;
  274.     long        fsize;
  275.     register long   bsize;
  276.  
  277.     if (curwp->w_markp == NULL) {
  278.     return (FALSE);
  279.     }
  280.  
  281.     if (curwp->w_dotp == curwp->w_markp) {
  282.     rp->r_linep = curwp->w_dotp;
  283.     if (curwp->w_doto < curwp->w_marko) {
  284.         rp->r_offset = curwp->w_doto;
  285.         rp->r_size = curwp->w_marko-curwp->w_doto;
  286.     } else {
  287.         rp->r_offset = curwp->w_marko;
  288.         rp->r_size = curwp->w_doto-curwp->w_marko;
  289.     }
  290.     return (TRUE);
  291.     }
  292.  
  293.     blp = curwp->w_dotp;
  294.     bsize = curwp->w_doto;
  295.     flp = curwp->w_dotp;
  296.     fsize = llength(flp)-curwp->w_doto+1;
  297.     while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  298.     if (flp != curbp->b_linep) {
  299.         flp = lforw(flp);
  300.         if (flp == curwp->w_markp) {
  301.         rp->r_linep = curwp->w_dotp;
  302.         rp->r_offset = curwp->w_doto;
  303.         rp->r_size = fsize + curwp->w_marko;
  304.         return (TRUE);
  305.         }
  306.  
  307.         fsize += llength(flp) + 1;
  308.     }
  309.  
  310.     if (lback(blp) != curbp->b_linep) {
  311.         blp = lback(blp);
  312.         bsize += llength(blp)+1;
  313.         if (blp == curwp->w_markp) {
  314.         rp->r_linep = blp;
  315.         rp->r_offset = curwp->w_marko;
  316.         rp->r_size = bsize - curwp->w_marko;
  317.         return (TRUE);
  318.         }
  319.     }
  320.     }
  321.  
  322.     emlwrite("Bug: lost mark", NULL);
  323.     return (FALSE);
  324. }
  325.  
  326.  
  327. /*
  328.  * set the highlight attribute accordingly on all characters in region
  329.  */
  330. markregion(attr)
  331.     int attr;
  332. {
  333.     register LINE   *linep;
  334.     register int    loffs;
  335.     register int    s;
  336.     REGION          region;
  337.     CELL            ac;
  338.  
  339.     if ((s=getregion(®ion)) != TRUE)
  340.       return (s);
  341.  
  342.     lchange(WFHARD);
  343.     linep = region.r_linep;
  344.     loffs = region.r_offset;
  345.     while (region.r_size--) {
  346.     if (loffs == llength(linep)) {
  347.         linep = lforw(linep);
  348.         loffs = 0;
  349.     } else {
  350.         ac = lgetc(linep, loffs);
  351.         ac.a = attr;
  352.         lputc(linep, loffs, ac);
  353.         ++loffs;
  354.     }
  355.     }
  356.  
  357.     return (TRUE);
  358. }
  359.  
  360.  
  361. /*
  362.  * clear all the attributes of all the characters in the buffer?
  363.  * this is real dumb.  Movement with mark set needs to be smarter!
  364.  */
  365. unmarkbuffer()
  366. {
  367.     register LINE   *linep;
  368.     register int     n;
  369.     CELL c;
  370.  
  371.     linep = curwp->w_linep;
  372.     while(lforw(linep) != curwp->w_linep){
  373.     n = llength(linep);
  374.     for(n=0; n < llength(linep); n++){
  375.         c = lgetc(linep, n);
  376.         c.a = 0;
  377.         lputc(linep, n, c);
  378.     }
  379.  
  380.     linep = lforw(linep);
  381.     }
  382.     
  383. }
  384.